#include "PrecompiledHeaders.h"
#include "SingleUserPlayState.h"
#include "ReplayState.h"
#include "MenuInGame.h"

SingleUserPlayState::SingleUserPlayState() : PlayState()
{
    desired_update_time = 1.0 / Constants::OGRE_NEWT_FRAMERATE;
    ghost_controller = NULL;
    GHOST_ON = false;
}

/*
 * Deal with a key press action
 */
bool SingleUserPlayState::keyPressed(const OIS::KeyEvent & e)
{
    switch (e.key)
    {
        // pause the game
        case OIS::KC_P:
        case OIS::KC_ESCAPE:
            menu->setLayout((LayoutType)PAUSE);
            pushGameState(findByName("in_game_menu"));
            break;
        
        // change input device to pod joystick
        case GameResources::POD_JOYSTICK:
            break;
            
        // change input device to mouse
        case GameResources::MOUSE:
            if(!resources->mouse) break;
            main_player->changeInputDevice(resources->mouse);
            resources->current_device = (InputDevice *)resources->mouse;
            break;
            
        // change input device to keyboard
        case GameResources::KEYBOARD:
            if(!resources->keyboard) break;
            main_player->changeInputDevice(resources->keyboard);
            resources->current_device = (InputDevice *)resources->keyboard;
            break;
            
        // change input device to joystick
        case GameResources::JOYSTICK:
            if(!resources->joystick) break;
            main_player->changeInputDevice(resources->joystick);
            resources->current_device = (InputDevice *)resources->joystick;
            break;

        // switch to first peron camera
        case OIS::KC_F:
            setCamera(resources->first_person_camera);
            resources->current_camera = (CameraControl *)resources->first_person_camera;
            break;
            
        // switch to third peron camera
        case OIS::KC_T:
            setCamera(resources->third_person_camera);
            resources->current_camera = (CameraControl *)resources->third_person_camera;
            break;
            
        // show/hide stats overlay
        case OIS::KC_S:
            if(stats_overlay->isVisible()) stats_overlay->hide();
            else if(overlays_enabled) stats_overlay->show();
            break;
            
        default:
            break;
    }
    return true;
}

/*
 * Set up main player to be controlled by the current input device. Add a ghost
 * if one is needed
 */
void SingleUserPlayState::initialisePlayers()
{
    // add the main player, and assign session
    if(!main_player) addPlayer(resources->current_level->getPlayer(), true);
    main_player->changeInputDevice(resources->current_device);
    main_player->setPlayState(this);
    main_player->setSession(session);
    main_player->usePod(resources->pod != NULL);
    ghost_file = menu->getGhostReplay();
    if(ghost_file.length() > 0) // if there is a file
    {
        if(!ghost)
        {
            ghost = resources->current_level->getPlayer()->clone(resources->scene_manager);
            addPlayer(ghost);
            ghost->setSession(new GameSession());
        }
        GHOST_ON = true;
        ghost_controller = new ReplayController(ghost_file);
        ghost_controller->setPlayState(this);
        ghost->changeInputDevice(ghost_controller);
        ghost->getSession()->setReplay(true);
        ghost->setPlayState(this);
    }
    else
    {
        if(ghost) ghost->hide();
        GHOST_ON = false;
    }
}

/*
 * Start all players recording their movements
 */
void SingleUserPlayState::startPlaying()
{
    out_file = fopen("PLAY.txt", "w");
    // initialise replay recordings
	unsigned int i;
    for(i = 0; i < players.size(); i++)
        players[i]->startRecording();
    play_speed = 1;
}

/*
 * stop all replay recordings, reset all players special objects and reset#
 * camera. Start replay state
 */
void SingleUserPlayState::stopPlaying()
{
    fclose(out_file);
    out_file = NULL;
    
	ReplayState::removeAllReplays();
    // stop, save and add the recording
    main_player->stopRecording();
    main_player->changeInputDevice(NULL);
    ReplayState::addReplay(new ReplayController(main_player->getReplay()));
    // add ghost replay
	if(GHOST_ON)
	{
	    ghost_controller->reset();
	    ReplayState::addReplay(ghost_controller);
	    ghost->changeInputDevice(NULL);
	}
    camera->reset();
    popGameState();
}

bool SingleUserPlayState::ogreNewtNeedsUpdate()
{
    if(GHOST_ON && !(ghost->isFinished())) return ghost_controller->ogreNewtNeedsUpdate(ogre_newt_time);
    else return ogre_newt_time >= desired_update_time;
}



float SingleUserPlayState::getOgreNewtUpdateTime()
{
    float ret;
    if(GHOST_ON && !(ghost->isFinished())) ret = ghost_controller->getOgreNewtUpdateTime();
    else ret = (ogre_newt_time > desired_update_time * 10) ? ogre_newt_time : desired_update_time;
    
    //fprintf(PlayState::out_file, "OgreNewt updated with %f seconds\n", ret); // replay debuffing info
    
    return ret;
}

void SingleUserPlayState::setStopPlaying()
{
    stop_playing = stop_playing || main_player->isFinished();
}

void SingleUserPlayState::playerFallout()
{
    // Respawn with reset scores and time
    PlayState::main_player->getSession()->resetLevelScore();
    updateScoreOverlay();
    std::string str;
    std::stringstream ss;
    Ogre::OverlayManager* overlay_manager = Ogre::OverlayManager::getSingletonPtr();
    Ogre::OverlayElement* hud_lives = overlay_manager->getOverlayElement("Hud/Lives/Text");
    ss << PlayState::main_player->getSession()->getNumLives();
    str = ss.str();
    hud_lives->setCaption(str);
    main_player->reset();
    if(ghost) ghost->reset();
    time_until_user_can_control = getTimeUntilUserCanControl();
    timer_goal = resources->current_level->seconds_for_level;
    camera->reset();
}
